package cn.basic.social.manager.handler.wxtalkhandler.impl;

import cn.basic.social.api.weixintalk.WxRequest;
import cn.basic.social.api.weixintalk.WxResponse;
import cn.basic.social.api.weixintalk.client.DefaultBaseWxTalkClient;
import cn.basic.social.api.weixintalk.client.BaseWxTalkClient;
import cn.basic.social.api.weixintalk.request.WxGetAccessTokenRequest;
import cn.basic.social.api.weixintalk.response.WxGetAccessTokenResponse;
import cn.basic.social.manager.config.ProviderConfig;
import cn.basic.social.manager.config.RedisCache;
import cn.basic.social.manager.handler.login.LoginRequest;
import cn.basic.social.manager.handler.login.LoginResponse;
import cn.basic.social.manager.handler.login.LoginService;
import cn.basic.social.manager.handler.wxtalkhandler.ThirdpartWxService;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;

/**
 * @ClassName WxGetAccessTokenServiceImpl
 * 文档地址：<a href="https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login/Wechat_Login.html"></a>
 * 1. 第三方发起微信授权登录请求，微信用户允许授权第三方应用后，微信会拉起应用或重定向到第三方网站，并且带上授权临时票据code参数；
 * 2. 通过code参数加上AppID和AppSecret等，通过API换取access_token；
 * 3. 通过access_token进行接口调用，获取用户基本数据资源或帮助用户实现基本操作。
 *
 * @Description 微信获取token
 * @Author zlf
 * @Date 2023/9/8 15:03
 */
@Slf4j
public class WxGetAccessTokenServiceImpl<T extends WxResponse, E extends WxRequest> implements ThirdpartWxService, LoginService {

    @Override
    public WxResponse invoke(WxRequest wxRequest, ProviderConfig providerConfig, RedisCache redisCache) throws Exception {

        BaseWxTalkClient wxTalkClient = new DefaultBaseWxTalkClient();

        WxGetAccessTokenResponse wxResponse = (WxGetAccessTokenResponse) wxTalkClient.doExecute(wxRequest, providerConfig.getAppid(), providerConfig.getSecret(), wxRequest.getLoginCode());

        log.info("微信获取token返回值：{}", JSON.toJSONString(wxResponse));

        return wxResponse;
    }

    @Override
    public LoginResponse invokeLogin(LoginRequest request, ProviderConfig providerConfig, RedisCache redisCache) throws Exception {
        WxGetAccessTokenRequest wxGetAccessTokenRequest = new WxGetAccessTokenRequest();
        wxGetAccessTokenRequest.setCode(request.getCode());
        WxGetAccessTokenResponse wxGetAccessTokenResponse = (WxGetAccessTokenResponse) this.invoke(wxGetAccessTokenRequest, providerConfig, redisCache);
        LoginResponse response = new LoginResponse(wxGetAccessTokenResponse.getOpenid(), null, JSON.toJSONString(wxGetAccessTokenResponse));
        return response;
    }
}
